package com.neusoft.yiyang.customer.service.impl;

import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.neusoft.yiyang.common.entity.bed.Bed;
import com.neusoft.yiyang.common.entity.bed.BedUsage;
import com.neusoft.yiyang.common.entity.customer.Customer;
import com.neusoft.yiyang.common.entity.customer.LeaveRequest;
import com.neusoft.yiyang.common.entity.customer.OutingRequest;
import com.neusoft.yiyang.common.entity.user.User;
import com.neusoft.yiyang.common.enums.BedStatus;
import com.neusoft.yiyang.common.enums.LeaveType;
import com.neusoft.yiyang.common.exception.BusinessException;
import com.neusoft.yiyang.customer.client.BedClient;
import com.neusoft.yiyang.customer.client.BedUsageClient;
import com.neusoft.yiyang.customer.client.UserClient;
import com.neusoft.yiyang.customer.mapper.CustomerMapper;
import com.neusoft.yiyang.customer.mapper.LeaveRequestMapper;
import com.neusoft.yiyang.customer.service.LeaveService;
import com.neusoft.yiyang.common.enums.ApprovalStatus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;


import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class LeaveServiceImpl implements LeaveService {

    @Autowired
    private LeaveRequestMapper leaveRequestMapper;
    @Autowired
    private CustomerMapper customerMapper;
    @Autowired
    private UserClient userClient;
    @Autowired
    private BedClient bedClient;
    @Autowired
    private BedUsageClient bedUsageClient;

    @Override()
    public Map<String, Object> createLeaveRequest(LeaveRequest leaveRequest) {
        Map<String, Object> result = new HashMap<>();

        // 使用QueryWrapper查询customer_id相同且状态为pending的记录
        QueryWrapper<LeaveRequest> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("customer_id", leaveRequest.getCustomerId())
                .eq("approval_status", ApprovalStatus.pending);

        List<LeaveRequest> pendingRequests = leaveRequestMapper.selectList(queryWrapper);
        if (!pendingRequests.isEmpty()) {
            // 存在重复记录，返回错误信息和已有记录ID
            result.put("success", false);
            result.put("message", "您已有待审批的退住申请，请勿重复提交");
            return result;
        }
        leaveRequest.setApprovalStatus(ApprovalStatus.pending);
        leaveRequestMapper.insert(leaveRequest);
        result.put("success", true);
        result.put("message", "退住申请提交成功");
        return result;
    }

    @Override
    public List<Map<String, Object>> getAllLeaveRequests() {
        List<LeaveRequest> leaveRequests = leaveRequestMapper.selectList(null);
        List<Map<String, Object>> result = new ArrayList<>();
        for (LeaveRequest request : leaveRequests) {
            Integer customerId = request.getCustomerId();
            Integer caretakerId = request.getCaretakerId();

            // 1. 客户不存在时抛出异常
            Customer customer = customerMapper.selectById(customerId);
            if (customer == null) {
                String msg = "退住申请ID=" + request.getLeaveRequestId() + "对应的客户ID=" + customerId + "不存在";
                System.out.println("[ERROR] " + msg);
                throw new BusinessException(4011, msg);
            }

            // 2. 护工不存在时抛出异常
            User user = userClient.getUserById(caretakerId);
            if (user == null) {
                String msg = "退住申请ID=" + request.getLeaveRequestId() + "对应的护工ID=" + caretakerId + "不存在";
                System.out.println("[ERROR] " + msg);
                throw new BusinessException(4012, msg);
            }

            // 3. 获取床位使用记录
            BedUsage bedUsage = bedUsageClient.getBedusageByCid(customerId);
            if (bedUsage == null) {
                System.out.println("[WARN] 客户ID=" + customerId + "未查询到床位使用记录，尝试使用客户表bed_id");
            }

            // 4. 无法获取床位ID时抛出异常
            Integer bedId = null;
            if (bedUsage != null) {
                bedId = bedUsage.getBedId();
            } else if (customer.getBedId() != null) {
                bedId = customer.getBedId();
                System.out.println("[DEBUG] 客户ID=" + customerId + "使用客户表bed_id：" + bedId);
            } else {
                String msg = "客户ID=" + customerId + "无床位使用记录且无关联床位，无法获取床位信息";
                System.out.println("[ERROR] " + msg);
                throw new BusinessException(4013, msg);
            }

            // 5. 床位不存在时抛出异常
            Bed bed = bedClient.getBed(bedId);
            if (bed == null) {
                String msg = "床位ID=" + bedId + "对应的床位信息不存在";
                System.out.println("[ERROR] " + msg);
                throw new BusinessException(4014, msg);
            }

            // 6. 组装结果（正常流程）
            Map<String, Object> map = new HashMap<>();
            map.put("leaveRequest", request);
            map.put("customerName", customer.getCustomerName());
            map.put("caretakerName", user.getName());
            map.put("buildingNo", bed.getBuildingNo());
            map.put("floor", bed.getFloor());
            map.put("roomNumber", bed.getRoomNumber());
            map.put("bedNo", bed.getBedNo());
            result.add(map);
        }
        return result;
    }

    //获取护工对应的客户退住记录
    public List<Map<String, Object>> getLeaveRequestsByCaretakerId(Integer caretakerId) {
        QueryWrapper<LeaveRequest> qw = new QueryWrapper<>();
        qw.eq("caretaker_id", caretakerId);
        List<LeaveRequest> leaveRequests = leaveRequestMapper.selectList(qw);
        List<Map<String, Object>> result = new ArrayList<>();
        for (LeaveRequest leaveRequest : leaveRequests) {
            Customer customer = customerMapper.selectById(leaveRequest.getCustomerId());
            Map<String, Object> map = new HashMap<>();
            map.put("customer", customer);
            map.put("leaveRequest", leaveRequest);
            result.add(map);
        }
        return result;
    }

    @Override
    public LeaveRequest getLeaveRequestById(Integer leaveRequestId) {
        return leaveRequestMapper.selectById(leaveRequestId);
    }

    @Override
    public void updateLeaveRequestStatus(Integer leaveRequestId, String status) {
        LeaveRequest leaveRequest = leaveRequestMapper.selectById(leaveRequestId);
        if (leaveRequest != null) {
            // 将String类型的status转换为ApprovalStatus枚举类型
            leaveRequest.setApprovalStatus(ApprovalStatus.valueOf(status));  // 转换
            leaveRequestMapper.updateById(leaveRequest);
        }
    }

    @Override
    public void rejectLeaveRequest(Integer leaveRequestId) {
        LeaveRequest leaveRequest = leaveRequestMapper.selectById(leaveRequestId);
        leaveRequest.setApprovalStatus(ApprovalStatus.rejected);
        //更新审批人没写
        leaveRequest.setApprovalTime(java.sql.Timestamp.valueOf(LocalDateTime.now()));
        leaveRequestMapper.updateById(leaveRequest);
    }

    @Override
    public void agreeLeaveRequest(Integer leaveRequestId) {
        LeaveRequest leaveRequest = leaveRequestMapper.selectById(leaveRequestId);
        if (leaveRequest.getLeaveType() != LeaveType.keep_bed) {
            Customer customer = customerMapper.selectById(leaveRequest.getCustomerId());
            BedUsage bedUsage = bedUsageClient.getBedusageByCid(customer.getCustomerId());
            Bed bed = bedClient.getBed(bedUsage.getBedId());
            bed.setStatus(BedStatus.free);
            bedClient.updateBed(bed);
            UpdateWrapper<Customer> wrapper = new UpdateWrapper<>();
            wrapper.eq("customer_id", customer.getCustomerId())
                    .set("bed_id", null)
                    .set("caretaker_id", null)
                    .set("contract_end_date", LocalDateTime.now())
                    .set("is_deleted", 1);
            customerMapper.update(null, wrapper);
            bedUsage.setEndDate(java.sql.Timestamp.valueOf(LocalDateTime.now()));
            bedUsageClient.updateBedUsage(bedUsage);
        } else {
            Customer customer = customerMapper.selectById(leaveRequest.getCustomerId());
            BedUsage bedUsage = bedUsageClient.getBedusageByCid(customer.getCustomerId());
            UpdateWrapper<Customer> wrapper = new UpdateWrapper<>();
            wrapper.eq("customer_id", customer.getCustomerId())
                    .set("caretaker_id", null)
                    .set("contract_end_date", LocalDateTime.now())
                    .set("is_deleted", 1);
            customerMapper.update(null, wrapper);
            bedUsage.setEndDate(java.sql.Timestamp.valueOf(LocalDateTime.now()));
            bedUsageClient.updateBedUsage(bedUsage);
        }
        leaveRequest.setApprovalStatus(ApprovalStatus.approved);
        leaveRequest.setApprovalTime(java.sql.Timestamp.valueOf(LocalDateTime.now()));
        leaveRequestMapper.updateById(leaveRequest);
    }


    //根据姓名查询
    @Override
    public List<Map<String, Object>> searchByCustomerName(String customerName) {
        // 1. 模糊查询所有匹配客户
        QueryWrapper<Customer> wrapper = new QueryWrapper<>();
        wrapper.like("customer_name", customerName);
        List<Customer> matchedCustomers = customerMapper.selectList(wrapper);

        if (matchedCustomers.isEmpty()) return new ArrayList<>();

        // 2. 获取所有匹配的 customerId
        List<Integer> customerIds = matchedCustomers.stream()
                .map(Customer::getCustomerId)
                .collect(Collectors.toList());

        // 3. 查找所有对应的 LeaveRequest
        QueryWrapper<LeaveRequest> lrWrapper = new QueryWrapper<>();
        lrWrapper.in("customer_id", customerIds);
        List<LeaveRequest> leaveRequests = leaveRequestMapper.selectList(lrWrapper);

        List<Map<String, Object>> result = new ArrayList<>();

        for (LeaveRequest request : leaveRequests) {
            Customer customer = matchedCustomers.stream()
                    .filter(c -> c.getCustomerId().equals(request.getCustomerId()))
                    .findFirst().orElse(null);

            User user = userClient.getUserById(request.getCaretakerId());
            BedUsage bedUsage = bedUsageClient.getBedusageByCid(request.getCustomerId());
            Bed bed = bedClient.getBed(bedUsage.getBedId());

            Map<String, Object> map = new HashMap<>();
            map.put("leaveRequest", request);
            map.put("customerName", customer != null ? customer.getCustomerName() : null);
            map.put("userName", user != null ? user.getUsername() : null);
            map.put("buildingNo", bed != null ? bed.getBuildingNo() : null);
            map.put("floor", bed != null ? bed.getFloor() : null);
            map.put("roomNumber", bed != null ? bed.getRoomNumber() : null);
            map.put("bedNo", bed != null ? bed.getBedNo() : null);
            result.add(map);
        }

        return result;
    }

    //删除退住申请
    @Override
    public void deletLeaveRequest(Integer leaveRequestId) {
        leaveRequestMapper.deleteById(leaveRequestId);
    }

    //编辑退住申请
    @Override
    public void updateLeaveRequest(Integer leaveRequestId, LeaveRequest updateRequest) {
        LeaveRequest existingRequest = leaveRequestMapper.selectById(leaveRequestId);
        System.out.println(existingRequest);
        existingRequest.setLeaveType(updateRequest.getLeaveType());
        existingRequest.setPlannedLeaveDate(updateRequest.getPlannedLeaveDate());
        existingRequest.setReason(updateRequest.getReason());
        System.out.println(existingRequest);
        leaveRequestMapper.updateById(existingRequest);
    }

}
